package com.telecom.util;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class XMLFactory {
    //缓存已经解析出来的bean配置
    private static final Map<String, Class<?>> BEAN_CLASS_MAP = new HashMap<>();
    private static final String CONFIG_FILE = "config.xml";

    static {
        try (InputStream inputStream = XMLFactory.class.getClassLoader().getResourceAsStream(CONFIG_FILE)) {
            if (inputStream == null) {
                throw new RuntimeException("未找到配置文件");
            }
            SAXReader reader = new SAXReader();
            Document doc = reader.read(inputStream);
            Element rootElement = doc.getRootElement();
            List<Element> beans = rootElement.elements("bean");
            for (Element bean : beans) {
                String id = bean.attributeValue("id");//id="dao"
                String className = bean.attributeValue("class");//com.telecom.dao.impl.UserDaoJdbcImpl
                if (id == null || id.trim().isEmpty() || className == null || className.trim().isEmpty()) {
                    throw new RuntimeException("bean标签的id和class属性不能为空");
                }
                BEAN_CLASS_MAP.put(id, Class.forName(className));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> Optional<T> getBean(String id) {
        Class<?> clazz = BEAN_CLASS_MAP.get(id);
        if (clazz == null) {
            return Optional.empty();
        }
        try {
            //判断类是否可实例化
            if (clazz.isInterface() || clazz.isAnnotation() || clazz.isAssignableFrom(Enum.class) || clazz.isPrimitive()) {
                throw new RuntimeException("类不可实例化:" + clazz.getName());
            }
            Class<T> typeClass = (Class<T>) clazz;
            Constructor<T> constructor = typeClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            T t = constructor.newInstance();
            return Optional.of(t); //将t对象存储在optional中，并返回
        } catch (Exception e) {
            throw new RuntimeException("创建对象失败");
        }
        //实例化类的对象

    }
}
